﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace KUMC.Neurology.SomatoTopo
{
    enum Showing { DISTRIBUTION, CLINIC };

    partial class FormSubject : Form
    {
        /*
         * Member
         * */
        private Study m_Study = null;
        private Subject m_Subject = null;
        private int m_iSubject;
        private Showing m_Showing;
        private TextBox[] m_tbInput = null;
        private Label[] m_lbInput = null;
        private bool m_bAddSubject = false;
        //private bool m_bEraser = false;

        private Bitmap m_DistDisplay = null;

        private List<Point> m_Points = null;

        private const int TOOLBAR_HEIGHT = 25;
        private const int STATUSBAR_HEIGHT = 22;
        private const int PANEL_MARGIN = 3;
        private const int TB_HEIGHT = 21;
        private const int TB_WIDTH = 240;
        private const int MARGIN = 5;
        private const int LB_HEIGHT = 21;
        private const int LB_WIDTH = 150;

        /*
         * Constructor
         * */
        public FormSubject()
        {
            InitializeComponent();
        }
        public FormSubject(Study study, int index)
            : this()
        {
            this.m_Study = study;
            this.m_iSubject = index;
            this.m_Showing = Showing.DISTRIBUTION;
            this.m_Points = new List<Point>();
        }
        public FormSubject(Study study)
            : this(study, 0)
        {
        }

        /*
         * Event
         * */
        private void SubjectForm_Load(object sender, EventArgs e)
        {
            this.InitControls();
            this.CheckShowing();
            this.UpdatePicturebox();
            this.Layout2Form();
            this.UpdateStatusBar();
        }
        private void SubjectForm_Resize(object sender, EventArgs e)
        {
            this.Layout2Form();
        }

        private void pbSubject_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(this.m_Study.Template.Bitmap, 0, 0);
            if (this.m_DistDisplay != null)
            {
                e.Graphics.DrawImage(this.m_DistDisplay, 0, 0);
            }
        }
        private void pbSubject_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                m_Points.Add(e.Location);
                if (m_Points.Count > 1)
                {
                    using (Pen pen = new Pen(Brushes.Black))
                    {
                        pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                        this.pbSubject.CreateGraphics().DrawLines(pen, m_Points.ToArray());
                    }
                }

            }
            else if (e.Button == MouseButtons.Right)
            {
                if (m_Points.Count > 2)
                {
                    FormSubFilt form = new FormSubFilt(m_Study.DistributionOption);
                    if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        // max disp option = 6, 4bit * 6 = 24bit
                        int code = Utility.Incoding(form.DistOption);
                        
                        SolidBrush brush = new SolidBrush(Color.FromArgb(255, Color.FromArgb(code)));
                        Graphics.FromImage(m_DistDisplay).FillPolygon(brush, m_Points.ToArray());
                        
                        //this.m_DistDisplay.FillRegion(m_Points.ToArray(), code);
                        //this.pbSubject.CreateGraphics().Clear(Color.Transparent);
                        this.pbSubject.Invalidate();
                        m_Points.Clear();
                    }
                }
            }
        }        

        /*
         * Tool
         * */
        private void toolStripBtnPrev_Click(object sender, EventArgs e)
        {
            if (this.PrevSubject())
            {
                if (this.m_Showing == Showing.DISTRIBUTION)
                {
                    this.UpdatePicturebox();
                }
                else if (this.m_Showing == Showing.CLINIC)
                {
                    this.UpdateTextboxes();
                }
            }
        }
        private void toolStripBtnNext_Click(object sender, EventArgs e)
        {
            if (this.NextSubject())
            {
                if (this.m_Showing == Showing.DISTRIBUTION)
                {
                    this.UpdatePicturebox();
                }
                else if (this.m_Showing == Showing.CLINIC)
                {
                    this.UpdateTextboxes();
                }
            }
        }
        private void distributionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.m_Showing == Showing.CLINIC)
            {
                this.m_Showing = Showing.DISTRIBUTION;
                this.CheckShowing();

                if (!this.m_bAddSubject)
                {
                    this.UpdatePicturebox();
                }
            }
        }
        private void clinicalDataToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.m_Showing == Showing.DISTRIBUTION)
            {
                this.m_Showing = Showing.CLINIC;
                this.CheckShowing();

                if (!this.m_bAddSubject)
                {
                    this.UpdateTextboxes();
                }
            }
        }
        private void toolStripAddSubject_Click(object sender, EventArgs e)
        {
            int width = m_Study.Template.Size.Width;
            int height = m_Study.Template.Size.Height;
            int len = this.m_Study.SubjectOption.Length;
            this.toolStripBtnPrev.Enabled = false;
            this.toolStripBtnNext.Enabled = false;
            this.m_bAddSubject = true;

            // Clear All
            for (int i = 0; i < len; i++) { this.m_tbInput[i].Text = ""; }
            m_DistDisplay = new Bitmap(width, height, PixelFormat.Format32bppArgb);

            this.m_Showing = Showing.CLINIC;
            this.CheckShowing();
        }
        private void toolStripDelSubject_Click(object sender, EventArgs e)
        {
            //this.m_bEraser = true;
            this.m_Study.DelSubject(m_Subject);
            this.UpdatePicturebox();
            this.UpdateTextboxes();
        }
        private void toolStripSave_Click(object sender, EventArgs e)
        {
            int len = this.m_Study.SubjectOption.Length;
            string[] option = new string[len];
            for (int i = 0; i < len; i++) { option[i] = this.m_tbInput[i].Text; }
            int[] distribution = Utility.Bitmap2Data(m_DistDisplay);

            if (this.m_bAddSubject)
            {                
                m_Subject = new Subject(option, distribution);
                m_iSubject = this.m_Study.GetSubjectCount();
                this.m_Study.AddSubject(m_Subject);                
            }
            else
            {
                m_Subject.Option = option;
                m_Subject.Distribution = distribution;
            }
            pbSubject.CreateGraphics().Clear(Color.Transparent);
            Graphics.FromImage(m_DistDisplay).Clear(Color.Transparent);
            
            //this.m_Showing = Showing.DISTRIBUTION;
            this.UpdatePicturebox();
            this.UpdateStatusBar();
            this.CheckShowing();

            this.toolStripBtnPrev.Enabled = true;
            this.toolStripBtnNext.Enabled = true;
            this.m_bAddSubject = false;

        }
        private void toolStripCancel_Click(object sender, EventArgs e)
        {
            this.m_iSubject = 0;
            this.m_Showing = Showing.DISTRIBUTION;
            this.UpdatePicturebox();
            this.CheckShowing();
        }

        
        /*
         * Methods
         * */
        private void InitControls()
        {
            int n = m_Study.SubjectOption.Length;
            int pnWidth = (MARGIN * 5) + LB_WIDTH + MARGIN + TB_WIDTH + (MARGIN * 5);
            int pnHeight = (MARGIN * 5) + (n * TB_HEIGHT) + (n * MARGIN) + (MARGIN * 5);

            this.pnClinicalControlGroup.Location = new Point(PANEL_MARGIN, PANEL_MARGIN);
            this.pnClinicalControlGroup.Size = new Size(pnWidth, pnHeight);

            this.m_lbInput = new Label[n];
            this.m_tbInput = new TextBox[n];

            for (int i = 0; i < n; i++)
            {
                this.m_lbInput[i] = new Label();
                this.m_lbInput[i].Size = new Size(LB_WIDTH, LB_HEIGHT);
                this.m_lbInput[i].Location = new Point(MARGIN, (MARGIN + LB_HEIGHT) * (i + 1));
                this.m_lbInput[i].Text = m_Study.SubjectOption[i];
                this.m_lbInput[i].TextAlign = ContentAlignment.MiddleCenter;

                this.m_tbInput[i] = new TextBox();
                this.m_tbInput[i].Size = new Size(TB_WIDTH, TB_HEIGHT);
                this.m_tbInput[i].Location = new Point(MARGIN + LB_WIDTH + MARGIN, (MARGIN + TB_HEIGHT) * (i + 1));

            }
            this.pnClinicalControlGroup.Controls.AddRange(m_lbInput);
            this.pnClinicalControlGroup.Controls.AddRange(m_tbInput);
        }
        private void Layout2Form()
        {
            // Fit LayoutPanel to Form size
            Size size = this.ClientSize;
            size.Height = size.Height - TOOLBAR_HEIGHT - STATUSBAR_HEIGHT;
            flowLayoutPanel.Size = size;

            // Fit PictureBox to size of Template image
            this.pbSubject.Size = this.m_Study.Template.Bitmap.Size;
        }
        private bool NextSubject()
        {
            int n = this.m_Study.GetSubjectCount();
            if (this.m_iSubject < n - 1)
            {
                this.m_iSubject++;
                this.UpdateStatusBar();
                return true;
            }
            else
            {
                this.m_iSubject = n - 1;
                return false;
            }
        }
        private bool PrevSubject()
        {
            if (this.m_iSubject > 0)
            {
                this.m_iSubject--;
                this.UpdateStatusBar();
                return true;
            }
            else
            {
                this.m_iSubject = 0;
                return false;
            }
        }
        private void CheckShowing()
        {
            if (this.m_Showing == Showing.DISTRIBUTION)
            {
                this.distributionToolStripMenuItem.Text = Properties.Resources.MENU_CHKDISTRIBUTION;
                this.clinicalDataToolStripMenuItem.Text = Properties.Resources.MENU_UNCHKCLINIC;

                this.pbSubject.Visible = true;
                this.pbSubject.Invalidate();
                this.pnClinicalControlGroup.Visible = false;
            }
            else if (this.m_Showing == Showing.CLINIC)
            {
                this.distributionToolStripMenuItem.Text = Properties.Resources.MENU_UNCHKDISTRIBUTION;
                this.clinicalDataToolStripMenuItem.Text = Properties.Resources.MENU_CHKCLINIC;

                this.pbSubject.Visible = false;
                this.pnClinicalControlGroup.Visible = true;
            }
        }
        private void UpdateTextboxes()
        {
            if (this.m_Study.GetSubjectCount() > 0)
            {
                this.m_Subject = this.m_Study.GetSubject(m_iSubject);
                string[] row = this.m_Subject.Option;
                for (int i = 0; i < row.Length; i++)
                {
                    this.m_tbInput[i].Text = row[i];
                }
            }
            else
            {
                for (int i = 0; i < this.m_tbInput.Length; i++)
                {
                    this.m_tbInput[i].Text = "";
                }
            }
        }
        private void UpdatePicturebox()
        {
            if (this.m_Study.GetSubjectCount() > 0)
            {
                int width = m_Study.Template.Bitmap.Width;
                int height = m_Study.Template.Bitmap.Height;

                m_Subject = m_Study.GetSubject(m_iSubject);
                m_DistDisplay = Utility.Data2Bitmap(m_Subject.Distribution, width, height);
            }
            else
            {
                Bitmap bitmap = new Bitmap(m_Study.Template.Bitmap);
                Graphics g = Graphics.FromImage(bitmap);
                g.Clear(Color.White);

                Font font = new Font("Times New Roman", 60);
                g.DrawString("No Subject", font, Brushes.Black, 200, 200);

                this.m_DistDisplay = bitmap;
            }
            this.pbSubject.Invalidate();
        }
        private void UpdateStatusBar()
        {
            int current = this.m_iSubject + 1;
            int total = this.m_Study.GetSubjectCount();
            this.lbIndex.Text = current.ToString() + "/" + total.ToString();
        }        
    }
}